<template>
  <div class="snow-background">
    <canvas ref="canvasRef"></canvas>
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted, watch } from 'vue'

const props = defineProps({
  config: {
    type: Object,
    default: () => ({
      count: 100,
      speed: 'slow',
      wind: 'light',
      color: '#ffffff'
    })
  }
})

const canvasRef = ref(null)
let ctx = null
let snowflakes = []
let animationId = null

class Snowflake {
  constructor(canvas) {
    this.canvas = canvas
    this.reset()
    this.y = Math.random() * canvas.height
  }

  reset() {
    this.x = Math.random() * this.canvas.width
    this.y = -10
    this.size = Math.random() * 4 + 2
    this.speed = this.getSpeed()
    this.wind = this.getWind()
    this.wobble = Math.random() * Math.PI * 2
    this.wobbleSpeed = Math.random() * 0.05
    this.opacity = Math.random() * 0.6 + 0.4
  }

  getSpeed() {
    const speedMap = {
      slow: Math.random() * 1 + 0.5,
      medium: Math.random() * 2 + 1,
      fast: Math.random() * 3 + 2
    }
    return speedMap[props.config.speed] || speedMap.medium
  }

  getWind() {
    const windMap = {
      light: (Math.random() - 0.5) * 0.5,
      medium: (Math.random() - 0.5) * 1.5,
      strong: (Math.random() - 0.5) * 3
    }
    return windMap[props.config.wind] || windMap.medium
  }

  update() {
    this.y += this.speed
    this.wobble += this.wobbleSpeed
    this.x += Math.sin(this.wobble) + this.wind

    if (this.y > this.canvas.height) {
      this.reset()
    }

    if (this.x > this.canvas.width) {
      this.x = 0
    } else if (this.x < 0) {
      this.x = this.canvas.width
    }
  }

  draw(context) {
    context.save()
    context.globalAlpha = this.opacity
    
    const color = props.config.color || '#ffffff'
    
    // 雪花核心
    context.fillStyle = color
    context.beginPath()
    context.arc(this.x, this.y, this.size, 0, Math.PI * 2)
    context.fill()

    // 雪花光晕
    const gradient = context.createRadialGradient(
      this.x, this.y, 0,
      this.x, this.y, this.size * 2
    )
    gradient.addColorStop(0, color + 'aa')
    gradient.addColorStop(0.5, color + '44')
    gradient.addColorStop(1, color + '00')
    
    context.fillStyle = gradient
    context.beginPath()
    context.arc(this.x, this.y, this.size * 2, 0, Math.PI * 2)
    context.fill()

    context.restore()
  }
}

const init = () => {
  const canvas = canvasRef.value
  if (!canvas) return

  canvas.width = canvas.offsetWidth
  canvas.height = canvas.offsetHeight
  ctx = canvas.getContext('2d')

  snowflakes = []
  for (let i = 0; i < props.config.count; i++) {
    snowflakes.push(new Snowflake(canvas))
  }
}

const animate = () => {
  if (!ctx || !canvasRef.value) return

  ctx.clearRect(0, 0, canvasRef.value.width, canvasRef.value.height)

  snowflakes.forEach(snowflake => {
    snowflake.update()
    snowflake.draw(ctx)
  })

  animationId = requestAnimationFrame(animate)
}

const handleResize = () => {
  init()
}

onMounted(() => {
  init()
  animate()
  window.addEventListener('resize', handleResize)
})

onUnmounted(() => {
  if (animationId) {
    cancelAnimationFrame(animationId)
  }
  window.removeEventListener('resize', handleResize)
})

watch(() => props.config, () => {
  init()
}, { deep: true })
</script>

<style scoped>
.snow-background {
  width: 100%;
  height: 100%;
  position: absolute;
  top: 0;
  left: 0;
  background: linear-gradient(180deg, #2c3e50 0%, #34495e 50%, #2c3e50 100%);
}

canvas {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  display: block;
}
</style>

